package tools

import (
	"reflect"
)

func MapToStruct(m map[string]interface{}, s interface{}) error {
    for key, value := range m {
        fieldName, ok := getFieldForTag(s, "json", key)
        if !ok {
            continue
        }

        fieldValue := reflect.ValueOf(s).Elem().FieldByName(fieldName)
        if fieldValue.IsValid() {
            if fieldValue.Kind() == reflect.Ptr && fieldValue.Elem().Type().AssignableTo(reflect.TypeOf(value)) {
                newValue := reflect.New(fieldValue.Elem().Type())
                newValue.Elem().Set(reflect.ValueOf(value))
                fieldValue.Set(newValue)
            } else if fieldValue.Type().AssignableTo(reflect.TypeOf(value)) {
                fieldValue.Set(reflect.ValueOf(value))
            }
        }
    }
    return nil
}

func getFieldForTag(s interface{}, tag, value string) (string, bool) {
    rType := reflect.TypeOf(s).Elem()
    for i := 0; i < rType.NumField(); i++ {
        field := rType.Field(i)
        tagValue := field.Tag.Get(tag)
        if tagValue == value {
            return field.Name, true
        }
    }
    return "", false
}
